/**
 * @author adagys
 */

package com.eu.chipin.backend.db;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import com.eu.chipin.backend.*;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class DB {

	public static final String DATABASE_NAME = "chipin";
	
	private static ChipinOpenHelper helper = null;
	
	public static void initDB(Context context) {
		if (helper == null) {
			helper = new ChipinOpenHelper(context);
		}
	}
	/*
	 * Store a new trip object to the db
	 */
	public static void addTrip(Context context, Trip newTrip) {
		initDB(context);
		
		SQLiteDatabase db = helper.getWritableDatabase();
		
		ContentValues data = new ContentValues();
		data.put("name", newTrip.getName());
        System.out.println(data.get("name"));
		long tid = db.insert(Schema.TABLE_TRIPS, null, data);
		
		if (tid == -1) Log.e("DB", "Failed to insert a new trip");
		
		for (Member m: newTrip.getMembers()) {
			data.clear();
			data.put("tid", tid);
			data.put("cid", m.getContactId());
			db.insert(Schema.TABLE_PARTICIPANTS, null, data);
			data.clear();
			data.put("cid", m.getContactId());
			data.put("name", m.getName());
			db.insert(Schema.TABLE_MEMBERS, null, data);
		}
	}
	
	public static List<Trip> getTrips(Context context) {
      initDB(context);
      
      SQLiteDatabase db = helper.getReadableDatabase();
      Cursor c = db.query(Schema.TABLE_TRIPS, new String[]{"tid", "name"}, null, null, null, null, "timestamp DESC");
      
      List<Trip> trips = new ArrayList<Trip>();
      for (int i = 0, j = c.getCount(); i < j; i++) {
        c.moveToNext();
        Integer tid = c.getInt(0);
        String name = c.getString(1);
        System.out.println(name);
        List<Member> members = new ArrayList<Member>();
        Cursor d = db.query(Schema.TABLE_PARTICIPANTS, new String[]{"cid"}, "tid = " + tid, null, null, null, null);
        
        for (int k = 0, l = d.getCount(); k < l; k++) {
          d.moveToNext();
          Integer cid = d.getInt(0);
          Cursor e = db.query(Schema.TABLE_MEMBERS, new String[]{"name"}, "cid = " + cid, null, null, null, null);
          
          for (int m = 0, n = e.getCount(); m < n; m++) {
            e.moveToNext();
            String memberName = d.getString(0);            
            members.add(new Member(cid.toString(), memberName, null));
          }
        }      
        trips.add(new Trip(name, members));
      }
      return trips;
  }
	
	public static void addPurchase(Context context, Purchase newPurchase) {
		initDB(context);

		SQLiteDatabase db = helper.getWritableDatabase();
		ContentValues data = new ContentValues();
		float totalSum = 0;
		
		data.put("name", newPurchase.getName());
		data.put("tid", newPurchase.getTripId());
		long pid = db.insert(Schema.TABLE_PURCHASES, null, data);
		
		//Buyers
		for (Buyer b: newPurchase.getBuyers()) {
			data.clear();
			data.put("pid", pid);
			data.put("cid", b.getMemberId());
			data.put("sum", b.getSum());
			db.insert(Schema.TABLE_BUYERS, null, data);
			
			totalSum += b.getSum();
			//Update the balance
			updateBalance(b.getMemberId(), b.getSum(), newPurchase.getTripId());
		}
		
		//Chippers
		for (Chipper c: newPurchase.getChippers()) {
			data.clear();
			data.put("pid", pid);
			data.put("cid", c.getMemberId());
			data.put("sum", c.getSum());
			db.insert(Schema.TABLE_CHIPPERS, null, data);
		}
		
		splitCost(totalSum, newPurchase.getChippers(), newPurchase.getTripId());
	}
	
	public static void splitCost(float totalSum, LinkedList<Chipper> chippers, long tripId) {
		LinkedList<String> sharing = new LinkedList<String>();
		
		for (Chipper c: chippers) {
			if (c.isExclude()) {
				updateBalance(c.getMemberId(), -1.0f * c.getSum(), tripId);
				totalSum -= c.getSum();
			} else if (c.isAdditional()) {
					updateBalance(c.getMemberId(), -1.0f * c.getSum(), tripId);
					totalSum -= c.getSum();
					sharing.add(c.getMemberId());
			} else sharing.add(c.getMemberId());
		}
		float toPay = totalSum / (float) sharing.size();
		
		for (String cid: sharing) {
			updateBalance(cid, toPay, tripId);
		}
	}
	
	public static float getBalance(String memberId, long tripId) {
		SQLiteDatabase db = helper.getWritableDatabase();
		Cursor results = db.query(Schema.TABLE_BALANCE, new String[] {"balance"},
				 			      "tid = ? AND cid = ?", new String[] {String.valueOf(tripId), memberId}, null, null, null);
		results.moveToFirst();
		
		//TODO test retrieval
		String stringBalance = results.getString(0);
		
		float balance = Float.parseFloat(stringBalance);
		return balance; 
	}
	
	public static void updateBalance(String memberId, float sum, long tripId) {
		SQLiteDatabase db = helper.getWritableDatabase();
		ContentValues data = new ContentValues();
		
		float balance = getBalance(memberId, tripId);
		balance += sum;
		
		data.put("balance", balance);
		
		db.update(Schema.TABLE_BALANCE, data, "tid = ? AND cid = ?",
				  new String[] {String.valueOf(tripId), memberId});
	}
}
